home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1990, 1991 Stanford University
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the name
- * Stanford may not be used in any advertising or publicity relating to
- * the software without the specific, prior written permission of
- * Stanford.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT
- * ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY,
- * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
- /* $Header: /Source/Media/collab/TimeLine/RCS/canvas.c,v 1.0 91/09/30 16:49:33 chua Exp Locker: drapeau $ */
- /* $Log: canvas.c,v $
- * Revision 1.0 91/09/30 16:49:33 chua
- * Update to version 1.0
- *
- * Revision 0.73 91/09/19 17:28:39 chua
- * Make sure that variables are initialized properly. Change formatting slightly,
- * so that (if, for, while) statements with only one statement in them will not have
- * braces.
- *
- * Revision 0.72 91/08/16 16:55:56 chua
- * Moved the DrawCanvas repaint and event handlers to drawCanvas.c
- * The ScrollTimerNotify function is moved there as well.
- *
- * Revision 0.71 91/08/13 14:32:49 chua
- * In the DrawCanvasEventHandler, detect keyboard events as well. This is to allow
- * keyboard accelerators for the edit functions (Cut, Copy, Paste and Delete).
- * Cut, Copy and Paste are on the left keypad and Delete is either the Delete or
- * Backspace key.
- *
- * Also, when the mouse is moved into the DrawCanvas area, the canvas grabs the
- * keyboard focus.
- *
- * Revision 0.70 91/08/09 15:11:44 chua
- * Removed the event and repaint handlers for the App canvas. These are now placed
- * separately in a new file, appCanvas.c
- *
- * Revision 0.69 91/08/05 16:51:59 chua
- * Deleted the RepaintCanvas routine, as it is no longer necessary. In places where it
- * is called, just call the ScrollToFirstQuarter routine, which will do the necessary
- * repaint as well.
- *
- * Revision 0.68 91/08/05 13:00:52 chua
- * No change in code, just some formatting changes.
- *
- * Revision 0.67 91/08/02 14:26:35 chua
- * Made changes to DrawCanvasEventHandler so that when the mouse is moved off canvas when
- * dragging a note, the note will still be partially visible in the canvas when it is finally
- * 'dropped'.
- *
- * Revision 0.66 91/08/02 13:25:43 chua
- * Made changes to the moving note code so that it moves correctly under different zoom level
- * and across different canvas mappings.
- *
- * Revision 0.65 91/08/02 11:40:00 chua
- * In the ScrollTimerNotify and DrawCanvasEventHandler routines, make changes so that
- * dragging notes is now possible.
- *
- * Revision 0.64 91/07/26 17:21:08 chua
- * In DrawCanvasEventHandler, when an area is deselected, update the fields in the
- * region info popup window to zeros.
- * In DrawCanvasRepaintHandler, when checking if there is a need to draw a selected
- * area, check that the start of the selected area falls in the currently mapped
- * canvas.
- *
- * Revision 0.63 91/07/24 10:31:36 chua
- * In ScrollTimerNotify, return NOTIFY_DONE.
- *
- * Revision 0.62 91/07/22 15:15:58 chua
- * Changed the name of the pointer to the blank time popup window to InsertBlankTimePopup,
- * instead of a longer name previously.
- *
- * Revision 0.61 91/07/18 15:03:50 chua
- * In the DrawCanvasRepaintHandler routine, add the line, DrawGrid, before drawing the
- * instrument cables and notes.
- *
- * In the DrawCanvasEventHandler, if AddandDisplayNewNote is to be called, first move
- * the x position to the previous closest grid line, so that any new note added will be
- * 'snapped' to a grid line.
- *
- * Revision 0.60 91/07/17 10:15:14 chua
- * Changed the SetLineAttributes so that it accepts linewidth as a parameter.
- *
- * Moved four functions to moveCanvas.c. This are the functions concerned with
- * checking if scrolling needs to be done.
- *
- * Introduced a new timer notify function, ScrollTimerNotify, which is activated
- * when the user drags the mouse off the canvas while holding the left button down.
- * This function will automatically scroll the canvas, while increasing the area
- * selected accordingly.
- *
- * Changes are also made to the DrawCanvasEventHandler routine to incorporate the
- * timer notify function (like when to turn the timer on/off, etc).
- *
- * Revision 0.59 91/07/09 18:24:46 chua
- * Made changes to the startX, endX variables so that they now store the position at the
- * largest zoom level (zoom level = 1). Thus, the appropriate multiplication or
- * division by the zoom level has to be made when these variables are used. This will
- * include lastX (position of the playback head) as well.
- *
- * Revision 0.58 91/07/09 16:54:32 chua
- * In the DrawCanvasEventHandler, if the playback head is being repositioned, check that
- * a note is not selected. If a note was selected, set startX, endX, startY, endY to be
- * the same as for startnoteX etc, (since startX etc was changed when we click on the
- * canvas).
- *
- * Revision 0.57 91/06/25 15:49:56 chua
- * Replace all occurrences of the constant HalfSecondScale by the value 5, since the constant is no longer
- * in use.
- * Set the CANVAS_AUTO_SHRINK attribute to FALSE for all the three canvases. This is necessary so that
- * the actual canvas will be larger than the viewing window.
- * Add a new color, RED, to the colormap.
- * In the AppCanvasRepaintHandler, when calling the InstrumentDrawIcon routine, check if the instrument
- * has been selected and if so, pass in Sunken as the parameter when drawing the icon. If not, pass in
- * Raised as the parameter.
- *
- * Revision 0.56 91/06/05 16:13:31 chua
- * Delete the lines setting the attributes CANVAS_AUTO_SHRINK and CANVAS_AUTO_EXPAND for the
- * canvases (not required). Set the CANVAS_RETAINED attribute to FALSE for the AppCanvas
- * so that the repaint handler is called when the frame is resized.
- *
- * In the AppCanvasRepaintHandler, set the width of the AppCanvas as well as set the height
- * of the other canvases. (This is to avoid improper sizes of the canvases during resizing).
- *
- * Revision 0.55 91/06/04 17:37:10 chua
- * Added the copyright comments in the beginning of the file.
- *
- * Revision 0.54 91/06/04 17:19:23 chua
- * In the DrawCanvasEventHandler routine, only call DeleteNote if the frame is not a
- * Clipboard.
- *
- * In the DrawCanvasRepaintHandler routine, if the frame is a clipboard, draw a thick line
- * signifying the end of the clipboard on the canvas (so that the user can distinguish how
- * much space has been cut onto the clipboard.
- *
- * Revision 0.53 91/06/04 10:42:10 chua
- * Added a call to UpdateHeader whenever there is a change in the status of
- * the current document (the change flag set to 1).
- *
- * Revision 0.52 91/06/03 11:10:25 chua
- *
- *
- * Revision 0.51 91/05/28 12:09:32 chua
- * *** empty log message ***
- *
- * Revision 0.50 91/05/24 16:35:45 chua
- * *** empty log message ***
- *
- * Revision 0.49 91/05/23 17:28:52 chua
- * In the AppCanvasEventHandler, when an application is selected, update the message field in the
- * Insert Blank Time pop-up window, indicating which application was selected.
- * Similarly, in the AppCanvasRepaintHandler, update the message field to none, since clearing the
- * app canvas resets any selected application.
- *
- * Revision 0.48 91/05/22 16:37:40 chua
- * *** empty log message ***
- *
- * Revision 0.47 91/05/22 13:54:17 chua
- * Introduced a new variable, noteSelected, which keeps track of whether a note has been
- * selected.
- *
- * Revision 0.46 91/05/22 11:35:26 chua
- * *** empty log message ***
- *
- * Revision 0.45 91/05/17 16:56:42 chua
- * *** empty log message ***
- *
- * Revision 0.44 91/05/17 16:49:00 chua
- * Minor change in DrawCanvasEventHandler:
- *
- * When testing if areaSelected is to be set to one, a test is also made to make sure that the
- * starting and ending Y coordinates are not the same before setting areaSelected = 1.
- * Previously, only the X coordinates were tested.
- *
- * Revision 0.43 91/05/15 15:23:44 chua
- * When an area is selected, any currently selected note will be deselected first before the selected area
- * is drawn. This is to avoid confusion, since the edit functions (cut, paste, etc) can also be applied
- * to a selected note, or to a selected region. So it would be rather confusing to have both a selected
- * note and a selected region at the same time.
- *
- * Revision 0.42 1991/05/15 02:53:53 chua
- * In the DrawCanvasEventHandler, areaSelected is set to 1 only if startX != endX. This is
- * to ensure that an area has really been selected before setting the flag to true.
- *
- * Revision 0.41 1991/04/24 00:49:16 chua
- * Added code for dealing with selection procedures. These include some global variables
- * (areaSelected, startX, endX, startY, endY), and some static variables for dealing with scrolling
- * off the canvas window (scrollHorStart etc).
- * New Functions added are
- * CheckHorizontalScrolling
- * CheckVerticalScrolling
- *
- * Much of the DrawCanvasEventHandler routine is changed to accomodate dealing with selection.
- * Also, the DrawCanvasRepaintHandler is changed slightly so that the playback head is redrawn at
- * its original position after the canvas is redrawn with the new notes.
- *
- * Some minor changes were made in the SetCanvasHeight routine on the formula for calculating the
- * canvas heights.
- *
- * The font for the timeline time labels (in the TimeCanvas) is also set to "8x13".
- *
- * Revision 0.40 1991/03/29 01:31:00 chua
- * This file contains the functions for handling all the canvases.
- * There are three canvases used in the TimeLine Editor: AppCanvas, DrawCanvas and TimeCanvas.
- * CanvasInit is a function to initialize the variables and attributes for all the three canvases.
- * The VerticalScrollHandler and HorizontalScrollHandler functions enable two canvases to scroll simultaneously
- * either verticall or horizontally by the use of just one scroll bar (controlling both canvases)
- * InitializeCMSdata initializes the colormap for the canvases.
- * SetLineAttributes will set the line attribute for the graphics context (GC) used by the canvases.
- * SetCanvasHeight sets the height of each canvas according to how many open applications there are.
- * RepaintCanvas explicitly calls the repaint handlers of all three canvases to repaint all of them. This is done
- * when new data need to be shown, or when clearing all notes etc.
- * The other functions in this file are the event handlers (which are called when a user clicks or drags a mouse
- * in a canvas) and repaint handlers (either called explicitly, or automatically when the canvas has been damaged,
- * such as when another window overlaps it and is moved away).
- * */
-
- static char canvasrcsid[] = "$Header: /Source/Media/collab/TimeLine/RCS/canvas.c,v 1.0 91/09/30 16:49:33 chua Exp Locker: drapeau $";
-
- #include "main.h"
-
- int paletteName; /* Counter to differentiate between the different palette names */
- int scrollHorStart, scrollHorEnd; /* Horizontal start and end point of the canvas window */
- int scrollVerStart, scrollVerEnd; /* Vertical start and end point of the canvas window */
-
- /*
- * Initialization routine for the canvases.
- * There are three canvases used.
- * AppCanvas - Icons of the open applications are drawn here. The user can click on an icon to select a particular application.
- * DrawCanvas - The cables and notes for each application are drawn here. The playback head is also drawn on this canvas. This
- * is the 'editing' canvas, where notes are placed by the user.
- * TimeCanvas - The timeline (showing the time for the timeline document) is drawn here.
- * Called by the main program.
- */
- void CanvasInit(tlFrame)
- TimeLineFramePtr tlFrame;
- {
- u_char red[NumColors], green[NumColors], blue[NumColors]; /* arrays to hold the RGB values of the colormap */
- int i;
- int *xpixels; /* array used to hold the index values of the colormap */
- char cmsName[15]; /* Win CMS name */
- Notify_client Vobj, Hobj; /* Handlers to the scrollbar notify interpose procedures */
-
- tlFrame->paintWinDraw = canvas_paint_window(tlFrame->TimeLine_window->DrawCanvas); /* Get the paint window, display and drawable for all three */
- tlFrame->xidDraw =(Window) xv_get(tlFrame->paintWinDraw, XV_XID); /* canvases (Draw, App and Time) */
- tlFrame->dpyDraw = (Display *) xv_get(tlFrame->TimeLine_window->DrawCanvas, XV_DISPLAY);
- tlFrame->paintWinApp = canvas_paint_window(tlFrame->TimeLine_window->AppCanvas);
- tlFrame->xidApp =(Window) xv_get(tlFrame->paintWinApp, XV_XID);
- tlFrame->dpyApp = (Display *) xv_get(tlFrame->TimeLine_window->AppCanvas, XV_DISPLAY);
- tlFrame->paintWinTime = canvas_paint_window(tlFrame->TimeLine_window->TimeCanvas);
- tlFrame->xidTime =(Window) xv_get(tlFrame->paintWinTime, XV_XID);
- tlFrame->dpyTime = (Display *) xv_get(tlFrame->TimeLine_window->TimeCanvas, XV_DISPLAY);
-
- tlFrame->gc = XCreateGC(tlFrame->dpyDraw, tlFrame->xidDraw, 0, 0); /* Create the graphic context, one for drawing the playback head (gcLine),*/
- tlFrame->gcLine = XCreateGC(tlFrame->dpyDraw, tlFrame->xidDraw, 0,0); /* and the other for all other purposes (gc) (drawing notes, cables etc) */
- XSetFont(tlFrame->dpyTime, tlFrame->gc, XLoadFont(tlFrame->dpyTime, "8x13")); /* Load in a font for the GC */
- XSetFunction (tlFrame->dpyDraw, tlFrame->gcLine, GXxor); /* set to xor draw mode for the playback head GC so that the notes are not overwritten */
- SetLineAttributes(tlFrame, 2); /* set the line attributes of the draw gc */
- InitializeCMSdata(&(tlFrame->cms_data), red, green, blue); /* Initialize the color map segment and set up its RGB values */
-
- tlFrame->DrawScrollbarHor = xv_create(tlFrame->TimeLine_window->DrawCanvas, SCROLLBAR, /* create the canvas scrollbars */
- SCROLLBAR_DIRECTION, SCROLLBAR_HORIZONTAL, NULL);
- tlFrame->DrawScrollbarVer = xv_create(tlFrame->TimeLine_window->DrawCanvas, SCROLLBAR,
- SCROLLBAR_DIRECTION, SCROLLBAR_VERTICAL, NULL);
- tlFrame->AppScrollbar = xv_create(tlFrame->TimeLine_window->AppCanvas, SCROLLBAR,
- SCROLLBAR_DIRECTION, SCROLLBAR_VERTICAL, NULL);
- tlFrame->TimeScrollbar = xv_create(tlFrame->TimeLine_window->TimeCanvas, SCROLLBAR,
- SCROLLBAR_DIRECTION, SCROLLBAR_HORIZONTAL, NULL);
- tlFrame->TimeScrollbarV = xv_create(tlFrame->TimeLine_window->TimeCanvas, SCROLLBAR,
- SCROLLBAR_DIRECTION, SCROLLBAR_VERTICAL, NULL);
- Vobj = xv_get (tlFrame->AppScrollbar, SCROLLBAR_NOTIFY_CLIENT); /* set notify interpose functions to enable the canvases to scroll together */
- notify_interpose_event_func (Vobj, VerticalScrollHandler, NOTIFY_SAFE);
- Hobj = xv_get (tlFrame->DrawScrollbarHor, SCROLLBAR_NOTIFY_CLIENT); /* Interpose functions for the horizontal scrollbars */
- notify_interpose_event_func (Hobj, HorizontalScrollHandler, NOTIFY_SAFE);
-
- xv_set(tlFrame->DrawScrollbarVer, XV_SHOW, FALSE, NULL); /* Hide the draw canvas vertical scrollbar and the TimeLine scrollbars */
- xv_set(tlFrame->TimeScrollbar, XV_SHOW, FALSE, NULL); /* since only one vertical and one horizontal scrollbar are required */
- xv_set(tlFrame->TimeScrollbarV, XV_SHOW, FALSE, NULL);
-
- sprintf(cmsName, "palette%d", paletteName);
- paletteName++;
- xv_set(tlFrame->TimeLine_window->DrawCanvas, /* Initialize the Draw Canvas. This is the canvas on which the cable and */
- CANVAS_WIDTH, tlFrame->TimeLineLength, /* notes are drawn. The playback head is also drawn here. */
- CANVAS_AUTO_SHRINK, FALSE,
- WIN_CMS_NAME, cmsName,
- WIN_CMS_DATA, &(tlFrame->cms_data),
- NULL);
- xv_set(tlFrame->TimeLine_window->AppCanvas, /* Initialize the App Canvas. This is where the icons of the open applications */
- CANVAS_AUTO_SHRINK, FALSE,
- CANVAS_RETAINED, FALSE,
- WIN_CMS_NAME, cmsName,
- WIN_CMS_DATA, &(tlFrame->cms_data),
- NULL);
- xv_set(tlFrame->TimeLine_window->TimeCanvas, /* Initialize the TimeCanvas, where the timeline is drawn. */
- CANVAS_AUTO_SHRINK, FALSE,
- CANVAS_WIDTH, tlFrame->TimeLineLength,
- WIN_CMS_NAME, cmsName,
- WIN_CMS_DATA, &(tlFrame->cms_data),
- NULL);
- xpixels = (int *)xv_get(tlFrame->TimeLine_window->DrawCanvas,
- WIN_X_COLOR_INDICES); /* Get the indices in the colormap of the eight colors used and */
- for (i=0; i < NumColors; i++) /* store them in the pixelTable array */
- tlFrame->pixelTable[i] = xpixels[i];
- free (xpixels); /* No longer required */
- XSetForeground(tlFrame->dpyDraw, tlFrame->gcLine, /* Set the color of the playback head to BLACK by xoring with the background color */
- (long)tlFrame->pixelTable[Grey84]^(long)tlFrame->pixelTable[Black]);
- }
-
- /*
- * Initialize the colormap segment data and setup the RGB values.
- * Called by CanvasInit (canvas.c).
- */
- InitializeCMSdata(cms_data, red, green, blue)
- Xv_cmsdata *cms_data;
- unsigned char *red, *green, *blue;
- {
- (red)[Grey84] = 214; (green)[Grey84] = 214; (blue)[Grey84] = 214;
- (red)[Grey92] = 235; (green)[Grey92] = 235; (blue)[Grey92] = 235;
- (red)[Grey65] = 166; (green)[Grey65] = 166; (blue)[Grey65] = 166;
- (red)[White] = 255; (green)[White] = 255; (blue)[White] = 255;
- (red)[Red] = 255; (green)[Red] = 0; (blue)[Red] = 0;
- (red)[Unused2] = 235; (green)[Unused2] = 235; (blue)[Unused2] = 235;
- (red)[Unused3] = 211; (green)[Unused3] = 211; (blue)[Unused3] = 211;
- (red)[Black] = 0; (green)[Black] = 0; (blue)[Black] = 0;
- cms_data->type = XV_STATIC_CMS; /* By setting to STATIC instead of DYNAMIC, the existing colormap will be */
- /* used and the closest color that comes to those specified above will be */
- /* chosen. */
- cms_data->size = NumColors;
- cms_data->rgb_count = NumColors;
- cms_data->index = 0;
- cms_data->red = red;
- cms_data->green = green;
- cms_data->blue = blue;
- }
-
- /*
- * Function to set the line attributes of the graphics context.
- * Called by CanvasInit (canvas.c).
- */
- SetLineAttributes(tlFrame, linewidth)
- TimeLineFramePtr tlFrame;
- int linewidth;
- {
- int line_width = linewidth;
- int line_style = LineSolid;
- int cap_style = CapRound;
- int join_style = JoinRound;
- XSetLineAttributes(tlFrame->dpyDraw, tlFrame->gc, line_width, line_style, cap_style, join_style);
- }
-
- /*
- * Function to set the height of the canvases. This is done by checking the number of open applications and then setting the height attributes for
- * the three canvases.
- * Called by DrawCanvasRepaintHandler(canvas.c), UpdateAppsHandler(openApps.c).
- */
- void SetCanvasHeight(tlFrame)
- TimeLineFramePtr tlFrame;
- {
- int height; /* The height of the App canvas viewing window. */
- int position; /* Y position of the top left corner of the Time canvas */
-
- if (tlFrame->numberOfApps < 8)
- height = (tlFrame->numberOfApps + 1) * (IconHeight + IconGap) + (IconHeight/2);
- else
- height = (IconHeight + IconGap) * 8 + (IconHeight/2);
-
- position = xv_get(tlFrame->TimeLine_window->DrawCanvas, XV_Y); /* Get the position of the Draw canvas */
- position += height - (IconHeight + IconGap); /* Add the height of the Draw canvas to the position to obtain the desired */
- /* position for the Time canvas */
- xv_set(tlFrame->TimeLine_window->AppCanvas, /* Now set the height for all the three canvases */
- CANVAS_HEIGHT, (tlFrame->numberOfApps + 1) * (IconHeight + IconGap) + (IconHeight/2),
- XV_HEIGHT, height,
- NULL);
- xv_set(tlFrame->TimeLine_window->DrawCanvas,
- CANVAS_HEIGHT, (tlFrame->numberOfApps + 1) * (IconHeight + IconGap) + (IconHeight/2),
- XV_HEIGHT, height - (IconHeight + IconGap),
- NULL);
- xv_set(tlFrame->TimeLine_window->TimeCanvas,
- XV_Y, position,
- CANVAS_HEIGHT, (IconHeight + IconGap),
- XV_HEIGHT, (IconHeight + IconGap),
- NULL);
- window_fit_height(tlFrame->TimeLine_window->window);
- }
-
- /*
- * Event callback function for `TimeCanvas'.
- * At present, nothing is done in this event handler for the TimeCanvas.
- */
- Notify_value TimeCanvasEventHandler(win, event, arg, type)
- Xv_window win;
- Event *event;
- Notify_arg arg;
- Notify_event_type type;
- {
- return notify_next_event_func(win, (Notify_event) event, arg, type);
- }
-
- /*
- * Repaint callback function for `TimeCanvas'.
- * This function clears the TimeCanvas and redraws the timeline.
- */
- void TimeCanvasRepaintHandler(canvas, paint_window, display, xid, rects)
- Canvas canvas;
- Xv_window paint_window;
- Display *display;
- Window xid;
- Xv_xrectlist *rects;
- {
- TimeLineFramePtr tlFrame;
- TimeLine_window_objects *ip = (TimeLine_window_objects *) xv_get(canvas, XV_KEY_DATA, INSTANCE);
-
- tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)];
- XClearWindow(tlFrame->dpyTime, tlFrame->xidTime); /* clear the whole display in the TimeCanvas. */
- DrawTimeLine(tlFrame); /* Draw the timeline */
- }
-